module mculib.arm.core;

version(None):

package{
    import mculib.baremetal;

    ///回调函数
    alias CallHandler = void function();

    enum CorePeripheralAddress :size_t
    {
        /// 系统控制寄存器内存地址
        SCS_Base = 0xE000_E000,
        /// TIM 寄存器内存地址
        ITM_Base = 0xE000_0000,
        /// DWT 寄存器内存地址
        DWT_Base = 0xE000_1000,
        /// TPI 寄存器内存地址
        TPI_Base = 0xE004_0000,
        /// CoreDebug 寄存器内存地址
        CoreDebug_Base = 0xE000_EDF0,
        /// SysTick 寄存器内存地址 0xe000_e010 ~ 0xe000_e01f
        SysTick_Base = SCS_Base + 0x0010,
        /// NVIC 寄存器内存地址 0xe000_e100 ~ 0xe000_e4ef
        NVIC_Base = SCS_Base + 0x0100,
        /// SCB 寄存器内存地址, 
        SCB_Base = SCS_Base + 0x0D00,
        /// FPU 寄存器内存地址, 0xe000_ed88 ~ 0xe000_ed8b
        FPU_Base = SCS_Base + 0x0F30,
        FPU_CPACR = SCB_Base + 0x88,
        /// MPU 寄存器内存地址
        MPU_Base = SCS_Base + 0x0D90,
    }


    /// systick 寄存器, 0xe000_e010 ~ 0xe000_e01f
    struct STK_Type_UN
    {
        enum mask_CTRL {
            ENABLE = 1 << 0,                /// 使能
            TICKINT = 1 << 1,               /// 中断使能
            CLKSOURCE = 1 << 2,             /// 时钟源 0:AHB/8 1:AHB
            COUNTFLAG = 1 << 16,            /// 翻转标志,读取时位清除 0:未翻转 1:翻转
        }
        enum mask_LOAD {
            RELOAD = 0x00ff_ffff,           /// 重载值 24bit,
        }
        enum mask_VAL {
            CURRENT = 0x00ff_ffff,          /// 计数器当前值,写入时触发 CountFlag 置位
        }
        enum mask_CALIB {
            TENMS = 0x00ff_ffff,            /// 校准频率 参考 1ms HCLK/8
            SKEW = 1 << 30,                 /// 校准频率偏差 1:校准到1ms
            NOREF = 1 << 31,                /// 外部参考时钟 1:无外部参考时钟
        }
        @disable this();
        @Register("read-write",0x0) uint CTRL;
        @Register("read-write",0x4) uint LOAD;
        @Register("read-write",0x8) uint VAL;
        @Register("read-only",0xc) uint CALIB;
    }
    
    /// FPU 寄存器, 0xe000_ed88 ~ 0xe000_ed8b
    struct FPU_Type
    {
        /// FPCCR 掩码
        enum mask_FPCCR
        {
            LSPACT = 1 << 0,    /// 最后一次特权访问
            USER = 1 << 1,      /// 用户模式
            THREAD = 1 << 3,    /// 线程模式
            HFRDY = 1 << 4,     /// 半精度浮点就绪
            MMRDY = 1 << 5,     /// 双精度浮点就绪
            BFRDY = 1 << 6,     /// 单精度浮点就绪
            MONRDY = 1 << 8,    /// 监视器就绪
            LSPEN = 1 << 30,    /// 最后一次特权访问使能
            ASPEN = 1 << 31,    /// 所有特权访问使能
        }
        /// FPCAR 掩码
        enum mask_FPCAR
        {
            ADDRESS = uint.max,  /// 地址
        }
        /// FPDSCR 掩码
        enum mask_FPDSCR
        {
            IOC = 1 << 0,               /// 无效操作异常
            DZC = 1 << 1,               /// 除零异常
            OFC = 1 << 2,               /// 溢出异常
            UFC = 1 << 3,               /// 下溢异常
            IXC = 1 << 4,               /// 无效操作异常
            IDC = 1 << 7,               /// 无效操作异常
            RMODE = 1 << 22 | 1 << 23,  /// 舍入模式 舍入为零
            FZ = 1 << 24,               /// 除零异常
            DN = 1 << 25,               /// 无效操作异常
            AHP = 1 << 26,              /// 高精度模式
            V = 1 << 28,                /// 无效操作异常
            C = 1 << 29,                /// 无效操作异常
            Z = 1 << 30,                /// 无效操作异常
            N = 1 << 31,                /// 无效操作异常
        }
        /// MVFR0 掩码
        enum mask_MVFR0
        {
            A_SIMD = 0xf << 0,      /// SIMD
            A_FPMISC = 0xf << 4,    /// FPMISC
            A_SQRT = 0xf << 8,      /// SQRT
            A_DIVIDE = 0xf << 12,   /// DIVIDE
            T_SIMD = 0xf << 16,     /// SIMD
            T_FPMISC = 0xf << 20,   /// FPMISC
            T_SQRT = 0xf << 24,     /// SQRT
            T_DIVIDE = 0xf << 28,   /// DIVIDE
        }
        /// MVFR1 掩码
        enum mask_MVFR1
        {
            D_NAN = 0xf << 0,       /// NAN
            D_INF = 0xf << 4,       /// INF
            D_DENORM = 0xf << 8,    /// DENORM
            D_FZ = 0xf << 12,       /// FZ
            D_RMODE = 0xf << 16,    /// RMODE
            D_SAT = 0xf << 20,      /// SAT
            D_PACK = 0xf << 24,     /// PACK
            D_ROUND = 0xf << 28,    /// ROUND
        }
        @disable this();
        uint Reserved0;
        @Register("read-write",0x4) uint FPCCR;
        @Register("read-write",0x8) uint FPCAR;
        @Register("read-write",0xc) uint FPDSCR;
        @Register("read-write",0x10) uint MVFR0;
        @Register("read-write",0x14) uint MVFR1;
    }

    /// SCB 寄存器, 0xe000_ed00 ~ 0xe000_edff
    struct SCB_Type_UN
    {
        /// CPUID 掩码
        enum mask_CPUID
        {
            REVISION = 0xf << 0,        /// 修订号
            PARTNO = 0xfff << 4,        /// 部件号
            CONSTANT = 0xf << 16,       /// 常量
            VARIANT = 0xf << 20,        /// 变体
            IMPLEMENTER = 0xff << 24,   /// 实现者
        }
        /// 中断控制和状态寄存器
        enum mask_ICSR
        {
            VECTACTIVE = 0x1ff << 0,    /// 当前活动的中断号
            RETTOBASE = 1 << 11,        /// 返回基线
            VECTPENDING = 0x3f << 12,   /// 待处理的中断号
            ISRPENDING = 1 << 22,       /// 中断挂起
            ISRPREEMPT = 1 << 23,       /// 中断抢占
            PENDSTCLR = 1 << 25,        /// 清除挂起的SysTick中断
            PENDSTSET = 1 << 26,        /// 设置挂起的SysTick中断
            PENDSVCLR = 1 << 27,        /// 清除挂起的PendSV中断
            PENDSVSET = 1 << 28,        /// 设置挂起的PendSV中断
            NMIPENDSET = 1 << 31,       /// 设置挂起的NMI中断
        }
        /// 向量表偏移寄存器
        enum mask_VTOR
        {
            TBLOFF = uint.max,  /// 表偏移
        }
        /// 应用中断和复位控制寄存器
        enum mask_AIRCR
        {
            VECTRESET = 1 << 0,         /// 复位向量表  写入时必须为 0
            VECTCLRACTIVE = 1 << 1,     /// 清除活动中断 写入时必须为 0
            SYSRESETREQ = 1 << 2,       /// 系统复位请求
            PRIGROUP = 0x7 << 8,        /// 中断优先级分组
            ENDIANESS = 1 << 15,        /// 大小端
            VECTKEY = 0xffff << 16,     /// 寄存器写保护
        }
        /// 系统控制寄存器
        enum mask_SCR
        {
            SLEEPONEXIT = 1 << 1,       /// 退出睡眠模式
            SLEEPDEEP = 1 << 2,         /// 睡眠模式
            SEVONPEND = 1 << 4,         /// 使能挂起中断唤醒
        }
        /// 配置控制寄存器
        enum mask_CCR
        {
            NONBASETHRDENA = 1 << 0,    /// 非基线线程
            USERSETMPEND = 1 << 1,      /// 用户设置挂起中断
            UNALIGN_TRP = 1 << 3,       /// 未对齐访问
            DIV_0_TRP = 1 << 4,         /// 除零访问
            BFHFNMIGN = 1 << 8,         /// 忽略BusFault和HardFault
            STKALIGN = 1 << 9,          /// 栈对齐  0: 4字节对齐 1: 8字节对齐
            DC = 1 << 16,               /// 数据缓存
            IC = 1 << 17,               /// 指令缓存
            BP = 1 << 18,               /// 分支预测
        }
        /// 系统中断控制和状态寄存器
        enum mask_SHCSR
        {
            MEMFAULTACT = 1 << 0,       /// 内存管理中断
            BUSFAULTACT = 1 << 1,       /// 总线管理中断
            USGFAULTACT = 1 << 3,       /// 使用管理中断
            SVCALLACT = 1 << 7,         /// SVC中断
            MONITORACT = 1 << 8,        /// 监视器中断
            PENDSVACT = 1 << 10,        /// PendSV中断
            SYSTICKACT = 1 << 11,       /// SysTick中断异常位 1: 异常
            USGFAULTPENDED = 1 << 12,   /// 使用管理中断挂起
            MEMFAULTPENDED = 1 << 13,   /// 内存管理中断挂起
            BUSFAULTPENDED = 1 << 14,   /// 总线管理中断挂起
            SVCALLPENDED = 1 << 15,     /// SVC中断挂起
            MEMFAULTENA = 1 << 16,      /// 内存管理中断使能 1: 使能
            BUSFAULTENA = 1 << 17,      /// 总线管理中断使能 1: 使能
            USGFAULTENA = 1 << 18,      /// 使用管理中断使能 1: 使能
        }
        /// 故障状态寄存器
        enum mask_CFSR
        {
            IACCVIOL = 1 << 0,          /// 不可访问的指令
            DACCVIOL = 1 << 1,          /// 不可访问的数据
            MUNSTKERR = 1 << 3,         /// 未对齐的堆栈访问
            MSTKERR = 1 << 4,           /// 堆栈访问错误
            MLSPERR = 1 << 5,           /// 堆栈访问错误
            MMARVALID = 1 << 7,         /// MMAR有效
            IBUSERR = 1 << 8,           /// 总线错误
            PRECISERR = 1 << 9,         /// 精确数据访问错误
            IMPRECISERR = 1 << 10,      /// 不精确数据访问错误
            UNSTKERR = 1 << 11,         /// 未对齐的堆栈访问
            STKERR = 1 << 12,           /// 堆栈访问错误
            LSPERR = 1 << 13,           /// 堆栈访问错误
            BFARVALID = 1 << 15,        /// BFAR有效
            UNDEFINSTR = 1 << 16,       /// 未定义的指令
            INVSTATE = 1 << 17,         /// 无效的状态
            INVPC = 1 << 18,            /// 无效的PC
            NOCP = 1 << 19,             /// 无协处理器
            UNALIGNED = 1 << 24,        /// 未对齐的访问
            DIVBYZERO = 1 << 25,        /// 除零
        }
        /// 硬件故障寄存器
        enum mask_HFSR
        {
            VECTTBL = 1 << 1,           /// 向量表读取错误 
            FORCED = 1 << 30,           /// 强制硬件故障 1: 强制
            DEBUGEVT = 1 << 31,         /// 调试事件 必须写入0
        }
        /// 调试故障状态寄存器
        enum mask_DFSR
        {
            HALTED = 1 << 0,            /// 调试器挂起
            BKPT = 1 << 1,              /// 调试器断点
            DWTTRAP = 1 << 2,           /// DWT断点
            VCATCH = 1 << 3,            /// 调试器断点
            EXTERNAL = 1 << 4,          /// 外部断点
        }
        /// 内存管理故障地址寄存器
        enum mask_MMFAR
        {
            MMFAR = uint.max,           /// 内存管理故障地址
        }
        /// 总线故障地址寄存器
        enum mask_BFAR
        {
            BFAR = uint.max,            /// 总线故障地址
        }
        /// 辅助故障状态寄存器
        enum mask_AFSR
        {
            IMPDEF = uint.max,          /// 实现定义
        }

        /// CPACR 掩码
        enum mask_CPACR
        {
            CP10 = 1 << 20 | 1 << 21,   /// 协处理器10
            CP11 = 1 << 22 | 1 << 23,   /// 协处理器11
        }
        @disable this();
        @Register("read-only",0x0) uint CPUID;         /// CPUID 基本信息
        @Register("read-write",0x4) uint ICSR;          /// 中断控制和状态寄存器
        @Register("read-write",0x8) uint VTOR;          /// 向量表偏移寄存器
        @Register("read-write",0xc) uint AIRCR;         /// 应用中断和复位控制寄存器
        @Register("read-write",0x10) uint SCR;          /// 系统控制寄存器
        @Register("read-write",0x14) uint CCR;          /// 配置控制寄存器
        @Register("read-write",0x18) uint SHPR1;        /// 系统优先级寄存器1
        @Register("read-write",0x1c) uint SHPR2;        /// 系统优先级寄存器2
        @Register("read-write",0x20) uint SHPR3;        /// 系统优先级寄存器3
        @Register("read-write",0x24) uint SHCSR;        /// 系统中断控制和状态寄存器
        union
        {
            @Register("read-write",0x28) uint CFSR;         /// 故障状态寄存器
            struct{
                @Register("read-write",0x28) ubyte MMFSR;        /// 内存管理故障状态寄存器
                @Register("read-write",0x29) ubyte BFSR;         /// 总线故障状态寄存器
                @Register("read-write",0x2a) ushort UFSR;         /// 使用故障状态寄存器
            }    
        }
        @Register("read-write",0x2c) uint HFSR;         /// 硬件故障寄存器
        @Register("read-write",0x30) uint DFSR;         /// 调试故障状态寄存器
        @Register("read-write",0x34) uint MMFAR;        /// 内存管理故障地址寄存器
        @Register("read-write",0x38) uint BFAR;         /// 总线故障地址寄存器
        @Register("read-write",0x3c) uint AFSR;         /// 辅助故障状态寄存器
        @Register("read-write",0x40) uint[2] PFR;       /// 处理器特性寄存器
        @Register("read-write",0x48) uint DFR;          /// 调试特性寄存器
        @Register("read-write",0x4c) uint ADR;          /// 地址特性寄存器
        @Register("read-write",0x50) uint[4] MMFR;      /// 内存模型特性寄存器
        @Register("read-write",0x60) uint[5] ISAR;      /// 指令集特性寄存器
        @Register("unknown",0x74)uint[5] Reserved0;     /// 保留
        @Register("read-write",0x88) uint CPACR;        /// 协处理器访问控制寄存器
    }
    /// SCS 寄存器 系统控制寄存器, 0xe000_e000 ~ 0xe000_e010
    struct SCS_Type
    {
        enum mask_ICTR
        {
            INTLINESNUM = 0xf << 0,     /// 中断线数
        }
        enum mask_ACTLR
        {
            DISMCYCINT = 1 << 0,    /// 禁止多周期中断 置位禁止
            DISDEFWBUF = 1 << 1,    /// 禁止默认写缓冲
            DISFOLD = 1 << 2,       /// 禁止指令折叠
            DISFPCA = 1 << 8,       /// 禁止 FPCA 位
            DISOOFP = 1 << 9,       /// 禁止浮点溢出
            DISFZ = 1 << 30,        /// 禁止浮点除零
        }
        @disable this();
        @Register("read-only",0x0) uint ICTR;
        @Register("read-write",0x4) uint ACTLR;         /// 辅助控制寄存器

    }

    /// MPU 寄存器, 0xe000_ed90 ~ 0xe000_ed9f
    struct MPU_Type
    {
        @disable this();
        uint Reserved0;
        @Register("read-write",0x0) uint TYPER; /// MPU 类型寄存器
        @Register("read-write",0x4) uint CTRL;  /// MPU 控制寄存器
        @Register("read-write",0x8) uint RNR;   /// MPU 区域号寄存器
        @Register("read-write",0xc) uint RBAR;  /// MPU 基址寄存器
        @Register("read-write",0x10) uint RASR; /// MPU 属性寄存器
        @Register("read-write",0x14) uint RBAR_A1; /// MPU 基址寄存器
        @Register("read-write",0x18) uint RASR_A1; /// MPU 属性寄存器
        @Register("read-write",0x1c) uint RBAR_A2; /// MPU 基址寄存器
        @Register("read-write",0x20) uint RASR_A2; /// MPU 属性寄存器
    }
    /// NVIC 寄存器, 0xe000_e100 ~ 0xe000_e1ff
}

struct CorePeripheral
{
    //enum STK_Type* STK = MMIO!(CorePeripheralAddress.SysTick_Base,STK_Type);
    //enum FPU_Type* FPU = MMIO!(CorePeripheralAddress.FPU_Base,FPU_Type);
    //enum SCB_Type* SCB = MMIO!(CorePeripheralAddress.SCB_Base,SCB_Type);
    //enum MPU_Type* MPU = MMIO!(CorePeripheralAddress.MPU_Base,MPU_Type);
    enum SCS_Type* SCS = MMIO!(CorePeripheralAddress.SCS_Base,SCS_Type);
}
